package com.vip8.recorder.service.service;

import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.ResponseHeaderOverrides;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.vip8.recorder.api.model.dto.OssToken;
import com.vip8.recorder.service.utils.DateUtil;
import com.vip8.recorder.service.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

import static com.vip8.recorder.service.config.OssConfig.REGION_CN_HANGZHOU;

@Component
@Slf4j
public class OssManageService {
    @Resource
    OSSClient ossClient;
    @Value("${oss.bucketName}")
    private String bucketName;

    @Value("${oss.roleArn}")
    private String roleArn;
    @Resource
    private DefaultAcsClient acsClient;

    public static final String policy = "{\n" +
            "    \"Version\": \"1\",\n" +
            "    \"Statement\": [\n" +
            "        {\n" +
            "            \"Effect\": \"Allow\",\n" +
            "            \"Action\": [\n" +
            "                \"oss:GetObject\",\n" +
            "                \"oss:PutObject\"\n" +
            "            ],\n" +
            "            \"Resource\": \"acs:oss:*:1882897519163810:recorder01-daily/*\"\n" +
            "        }\n" +
            "    ]\n" +
            "}";

    /**
     * 判断文件是否存在
     * @param fileKey
     * @return
     */
    public boolean isExits(String fileKey){
        return ossClient.doesObjectExist(bucketName, fileKey);
    }

    /**
     * 上传文件
     *
     * @param fileKey
     * @param input
     */
    public void uploadFile(String fileKey, InputStream input) {
        try {
            ossClient.putObject(bucketName, fileKey, input);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }


    /**
     * 根据fileKey获取访问url
     */
    public String getUrlByFileKey(String fileKey) {
        GeneratePresignedUrlRequest reg = new GeneratePresignedUrlRequest(bucketName, fileKey, HttpMethod.GET);
        return getUrlByFileKey(fileKey, DateUtil.addHours(new Date(), 6), null);
    }

    /**
     * 根据fileKey获取访问url
     */
    public String getUrlByFileKey(String fileKey, Date expire, String fileName) {
        GeneratePresignedUrlRequest reg = new GeneratePresignedUrlRequest(bucketName, fileKey, HttpMethod.GET);
        reg.setExpiration(expire);
        if (StringUtil.isNotEmpty(fileName)) {
            ResponseHeaderOverrides headerOverrides = reg.getResponseHeaders();
            headerOverrides.setContentDisposition("attachment;filename=" + fileName);
        }
        URL url = ossClient.generatePresignedUrl(reg);
        if (url != null) {
            return url.toString().replace("http:", "https:");
        }
        return null;
    }


    public OssToken getOssDailyToken(){
        IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, "LTAI5tEgufMgQn4f24ePF9dT", "Y8l2nItqzu1WTIKB2JRkPmIRkzSOW4");
        DefaultAcsClient acsClient =  new DefaultAcsClient((profile));

        AssumeRoleRequest request = new AssumeRoleRequest();
        request.setMethod(MethodType.POST);
        request.setRoleArn("acs:ram::1882897519163810:role/stsrole");
//        request.setPolicy(policy);
        request.setRoleSessionName("test-001");

        AssumeRoleResponse response = null;
        try {
            response = acsClient.getAcsResponse(request);
            AssumeRoleResponse.Credentials credentials = response.getCredentials();

            OssToken ossToken = new OssToken();
            ossToken.setAccessKeyId(credentials.getAccessKeyId());
            ossToken.setAccessKeySecret(credentials.getAccessKeySecret());
            ossToken.setBucketName("recorder01-daily");
            ossToken.setProject("recorder");
            ossToken.setLogStore("qc-recorder");
            ossToken.setSecurityToken(credentials.getSecurityToken());
            ossToken.setExpiration(credentials.getExpiration());
            return  ossToken;

        } catch (ClientException e) {
            throw new RuntimeException(e);
        }
    }


    public OssToken getOssToken(){
        AssumeRoleRequest request = new AssumeRoleRequest();
        request.setMethod(MethodType.POST);
        request.setRoleArn(roleArn);
//        request.setPolicy(policy);
        request.setRoleSessionName("test-001");

        AssumeRoleResponse response = null;
        try {
            response = acsClient.getAcsResponse(request);
            AssumeRoleResponse.Credentials credentials = response.getCredentials();

            OssToken ossToken = new OssToken();
            ossToken.setAccessKeyId(credentials.getAccessKeyId());
            ossToken.setBucketName(bucketName);
            ossToken.setAccessKeySecret(credentials.getAccessKeySecret());
            ossToken.setSecurityToken(credentials.getSecurityToken());
            ossToken.setExpiration(credentials.getExpiration());
            return  ossToken;

        } catch (ClientException e) {
            throw new RuntimeException(e);
        }
    }
    public OssToken getOssToken(String roleArn, String roleSessionName, String policy, long expireSeconds){
        AssumeRoleRequest request = new AssumeRoleRequest();
        request.setMethod(MethodType.POST);
        request.setRoleArn(roleArn);
        request.setRoleSessionName(roleSessionName);
//        request.setPolicy(policy1);

        AssumeRoleResponse response = null;
        try {
            response = acsClient.getAcsResponse(request);
            AssumeRoleResponse.Credentials credentials = response.getCredentials();

            OssToken ossToken = new OssToken();
            ossToken.setAccessKeyId(credentials.getAccessKeyId());
            ossToken.setAccessKeySecret(credentials.getAccessKeySecret());
            ossToken.setSecurityToken(credentials.getSecurityToken());
            ossToken.setExpiration(credentials.getExpiration());
            return  ossToken;

        } catch (ClientException e) {
            throw new RuntimeException(e);
        }
    }
}
